Interaction example: Uber surge pricing

Data

Loading the Uber fares (price) data:

## Load commands
uber <- readr::read_rds("data/uber.rds")
register("uber")

Show the data description generated in the previous step.

Uber price

This dataset contains information on a sample of 1,000 Uber rides in San Diego between 8pm-12am

Variables:

Calculate some descriptive statistics of ride price per mile in the data.

result <- explore(
  uber, 
  vars = "price", 
  fun = c("mean", "sd", "min", "max"), 
  nr = 1
)
dtab(result) %>% render()

Show a frequency table for fs (i.e., is it Friday/Saturday or not) and ccon (i.e., is Comic Con in town or not)

result <- pivotr(uber, cvars = c("fs", "ccon"), nr = 2)
dtab(result) %>% render()

What do the correlations between the different variables look like.

result <- correlation(
  uber, 
  vars = c("price", "time", "fs", "ccon")
)
summary(result)
Correlation
Data        : uber 
Method      : Pearson 
Variables   : price, time, fs, ccon 
Null hyp.   : variables x and y are not correlated
Alt. hyp.   : variables x and y are correlated
** Variables of type {factor} included without adjustment **

Correlation matrix:
     price time  fs   
time -0.05            
fs    0.65  0.03      
ccon  0.42 -0.00  0.02

p.values:
     price time fs  
time 0.12           
fs   0.00  0.40     
ccon 0.00  0.95 0.61
plot(result, nrobs = 1000)

Questions to explore and effects to estimate

  1. Does the (start) time (time) of an Uber ride affect the price?
  2. Are rides on Friday/Saturday (“yes” or “no”) more or less expensive compared to rides on other days?
  3. Does the effect of (1) time of ride on price depend on (2) the day of the ride (i.e., Friday/Saturday or not)
  4. Are rides more or less expensive when ComicCon is in town (i.e., “yes” or “no”)?
  5. Does the (1) Comic Con effect on price depend on (2) the day of the ride (i.e., Friday/Saturday or not)?

Question 1: Does the (start) time of ride affect the price?

Lets start by visualizing if there seems to be a link between the time and price variables in the data.

visualize(
  uber, 
  xvar = "time", 
  yvar = "price", 
  type = "scatter", 
  nrobs = -1, 
  check = "line", 
  custom = FALSE
)

Looking at the graph, the line seems to be downward slopping but the effect looks pretty minimal.

We will use linear regression (Model > Linear regression) to estimate the effect of time on price and generate a prediction plot.

\[ price = a + b \times time \]

result <- regress(
  uber, 
  rvar = "price", 
  evar = "time"
)
summary(result, dec = 4)
Linear regression (OLS)
Data     : uber 
Response variable    : price 
Explanatory variables: time 
Null hyp.: the effect of time on price is zero
Alt. hyp.: the effect of time on price is not zero

             coefficient std.error  t.value p.value    
 (Intercept)      2.3388    0.0215 108.9574  < .001 ***
 time            -0.0002    0.0002  -1.5364  0.1248    

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-squared: 0.0024,  Adjusted R-squared: 0.0014 
F-statistic: 2.3605 df(1,998), p.value 0.1248
Nr obs: 1,000 
pred <- predict(
  result, 
  pred_cmd = "time = 0:240"
)
plot(pred, xvar = "time")

Although the slope in this (prediction) plot looks more impressive this is a bit misleading due to the Y-axis scale (i.e., compare to the scatter plot). The regression coefficient for time is negative but not statistically significant (i.e., p-value > 0.05)

Question 2. Are rides is on Friday/Saturday (“yes” or “no”) more or less expensive?

We will use linear regression (Model > Linear regression) to estimate the effect of fs on price, controlling for time, and generate a prediction plot.

result <- regress(uber, rvar = "price",  evar = c("time", "fs"))
summary(result, dec = 4)
Linear regression (OLS)
Data     : uber 
Response variable    : price 
Explanatory variables: time, fs 
Null hyp.: the effect of x on price is zero
Alt. hyp.: the effect of x on price is not zero

             coefficient std.error  t.value p.value    
 (Intercept)      2.2070    0.0169 130.3290  < .001 ***
 time            -0.0003    0.0001  -2.7544  0.0060 ** 
 fs|yes           0.4784    0.0175  27.3502  < .001 ***

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-squared: 0.43,  Adjusted R-squared: 0.4289 
F-statistic: 376.0794 df(2,997), p.value < .001
Nr obs: 1,000 
pred <- predict(
  result, 
  pred_cmd = c("time = 0:240", "fs = c('no', 'yes')")
)
plot(pred, xvar = "time", color = "fs")

The plot show a significant difference between prices charged on Friday and Saturday evening, compared to the other days of the week. The slope of the lines is, by assumption, the same in this model.

Now that we have included time and fs in the model time does seem to have a statistically significant downward effect.

coeff <- result$coeff$coefficient %>% 
  set_names(result$coeff$label)

visualize(
  uber,
  xvar = "time",
  yvar = "price",
  type = "scatter",
  custom = TRUE
) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"], 
      slope = coeff["time"], 
      color = "blue"
    ), 
    size = 1
  ) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"] + coeff["fs|yes"], 
      slope = coeff["time"], 
      color = "red"
    ), 
    size = 1
  ) +
  scale_color_manual(
    name = "Friday/Saturday",
    values = c(blue = "blue", red = "red"),
    labels = c("no", "yes")
    
  ) + 
  theme(legend.position = "bottom")

Question 3. Does the effect of (1) time of ride on price depend on (2) the day of the ride (i.e., Friday/Saturday or not)

Another way to state the question is to ask if it is reasonable that the slope of time in the previous prediction plot is the same for rides on Friday and Saturday as it is on other days.

If we assume that Uber is frequently used in the (late) evening by users visiting bars downtown, this may assumption of “equal slopes” may not be reasonable.

We will use linear regression (Model > Linear regression) to estimate the effect of fs, time, and interaction between fs and time on price and generate a prediction plot.

result <- regress(
  uber, 
  rvar = "price", 
  evar = c("time", "fs"),
  int = "time:fs"
)
summary(result)
Linear regression (OLS)
Data     : uber 
Response variable    : price 
Explanatory variables: time, fs 
Null hyp.: the effect of x on price is zero
Alt. hyp.: the effect of x on price is not zero

             coefficient std.error t.value p.value    
 (Intercept)       2.283     0.019 120.289  < .001 ***
 time             -0.001     0.000  -6.892  < .001 ***
 fs|yes            0.243     0.034   7.130  < .001 ***
 time:fs|yes       0.002     0.000   7.965  < .001 ***

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-squared: 0.464,  Adjusted R-squared: 0.463 
F-statistic: 287.567 df(3,996), p.value < .001
Nr obs: 1,000 
pred <- predict(
  result, 
  pred_cmd = c("time = 0:240", "fs = c('no', 'yes')")
)
plot(pred, xvar = "time", color = "fs")

Creating a scatter plot of the model results

coeff <- result$coeff$coefficient %>% 
  set_names(result$coeff$label)

visualize(
  uber,
  xvar = "time",
  yvar = "price",
  type = "scatter",
  custom = TRUE
) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"], 
      slope = coeff["time"], 
      color = "blue"
    ), 
    size = 1
  ) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"] + coeff["fs|yes"],
      slope = coeff["time"] + coeff["time:fs|yes"], 
      color = "red"
    ), 
    size = 1
  ) +
  scale_color_manual(
    name = "Friday/Saturday",
    values = c(blue = "blue", red = "red"),
    labels = c("no", "yes")
    
  ) + 
  theme(legend.position = "bottom")

The prediction plot provides compelling evidence that the “equal slopes” assumption may not be reasonable. We draw a similar conclusion by looking at a scatter plot of price and time with color set to fs.

visualize(
  uber, 
  xvar = "time", 
  yvar = "price", 
  type = "scatter", 
  nrobs = -1, 
  color = "fs", 
  check = "line", 
  custom = FALSE
)

Question 4. Are rides more or less expensive when ComicCon is in town (i.e., “yes” or “no”)?

We will use linear regression (Model > Linear regression) to estimate the effect of time, fs, ccon on price and generate a prediction plot. To simplify the interpretation lets remove the interaction between time and fs.

result <- regress(
  uber, 
  rvar = "price", 
  evar = c("time", "fs", "ccon"), 
)
summary(result, dec = 4)
Linear regression (OLS)
Data     : uber 
Response variable    : price 
Explanatory variables: time, fs, ccon 
Null hyp.: the effect of x on price is zero
Alt. hyp.: the effect of x on price is not zero

             coefficient std.error  t.value p.value    
 (Intercept)      2.1486    0.0145 148.4938  < .001 ***
 time            -0.0003    0.0001  -3.2402  0.0012 ** 
 fs|yes           0.4735    0.0147  32.3049  < .001 ***
 ccon|yes         0.3800    0.0185  20.5937  < .001 ***

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-squared: 0.6002,  Adjusted R-squared: 0.599 
F-statistic: 498.4851 df(3,996), p.value < .001
Nr obs: 1,000 
pred <- predict(
  result, 
  pred_cmd = c("time = 0:240", "ccon = c('no', 'yes')")
)
plot(pred, xvar = "time", color = "ccon")

The prediction plot provides compelling evidence that rides are more expensive during Comic Con.

Question 5. Does the (1) Comic Con effect on price depend on (2) the day of the ride (i.e., Friday/Saturday or not)?

Another way to state the question is to ask if it is reasonable that the difference in price between Friday/Saturday and on other days is the same when Comic Con is (not) in town.

We will use linear regression (Model > Linear regression) to estimate the effect of time, fs, and ccon and interaction between fs and ccon on price and generate a prediction plot.

result <- regress(
  uber, 
  rvar = "price", 
  evar = c("time", "fs", "ccon"), 
  int = "fs:ccon"
)
summary(result, dec = 4)
Linear regression (OLS)
Data     : uber 
Response variable    : price 
Explanatory variables: time, fs, ccon 
Null hyp.: the effect of x on price is zero
Alt. hyp.: the effect of x on price is not zero

                 coefficient std.error  t.value p.value    
 (Intercept)          2.1583    0.0145 148.9736  < .001 ***
 time                -0.0003    0.0001  -3.3800  < .001 ***
 fs|yes               0.4446    0.0158  28.0655  < .001 ***
 ccon|yes             0.3241    0.0220  14.7255  < .001 ***
 fs|yes:ccon|yes      0.1796    0.0395   4.5488  < .001 ***

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-squared: 0.6084,  Adjusted R-squared: 0.6068 
F-statistic: 386.428 df(4,995), p.value < .001
Nr obs: 1,000 
pred <- predict(
  result, 
  pred_cmd = c("time = 0:240", "fs = c('no', 'yes')", "ccon = c('no', 'yes')")
)
plot(pred, xvar = "time", facet_col = "ccon", color = "fs")

predict(
  result, 
  pred_cmd = c("time = 0", "fs = c('no', 'yes')", "ccon = c('no', 'yes')"),
  dec = 3
)
coeff <- result$coeff$coefficient %>% 
  set_names(result$coeff$label)

visualize(
  uber,
  xvar = "time",
  yvar = "price",
  type = "scatter",
  custom = TRUE
) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"] + coeff["fs|yes"] + coeff["ccon|yes"],
      slope = coeff["time"], 
      color = "blue"
    ), 
    size = 1
  ) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"], 
      slope = coeff["time"], 
      color = "black"
    ), 
    size = 1
  ) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"] + coeff["fs|yes"],
      slope = coeff["time"], 
      color = "red"
    ), 
    size = 1
  ) +
  geom_abline(
    aes(
      intercept = coeff["(Intercept)"] + coeff["ccon|yes"],
      slope = coeff["time"], 
      color = "green"
    ), 
    size = 1
  ) +
  scale_color_manual(
    name = "Friday/Saturday",
    values = c(blue = "blue", red = "red", black = "black", green = "green"),
    labels = c("no fs + no ccon", "fs + ccon", "no fs + ccon", "fs + no ccon")
    
  ) + 
  theme(legend.position = "bottom")

The final model

The previous model was missing the important interaction effect between time and fs. Lets now add that back in. This final model can be used to answer each of the previous question.

result <- regress(
  uber, 
  rvar = "price", 
  evar = c("time", "fs", "ccon"), 
  int = c("time:fs", "fs:ccon")
)
summary(result)
Linear regression (OLS)
Data     : uber 
Response variable    : price 
Explanatory variables: time, fs, ccon 
Null hyp.: the effect of x on price is zero
Alt. hyp.: the effect of x on price is not zero

                 coefficient std.error t.value p.value    
 (Intercept)           2.230     0.016 139.502  < .001 ***
 time                 -0.001     0.000  -8.098  < .001 ***
 fs|yes                0.224     0.029   7.843  < .001 ***
 ccon|yes              0.322     0.021  15.221  < .001 ***
 time:fs|yes           0.002     0.000   9.103  < .001 ***
 fs|yes:ccon|yes       0.174     0.038   4.585  < .001 ***

Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-squared: 0.639,  Adjusted R-squared: 0.637 
F-statistic: 351.15 df(5,994), p.value < .001
Nr obs: 1,000 
pred <- predict(
  result, 
  pred_cmd = c("time = 0:240", "fs = c('no', 'yes')", "ccon = c('no', 'yes')")
)
plot(pred, xvar = "time", facet_col = "ccon", color = "fs")

Finally, lets visualize the effects in a scatter plot. Looks a lot like the prediction plots from the last regression

visualize(
  uber, 
  xvar = "time", 
  yvar = "price", 
  type = "scatter", 
  nrobs = -1, 
  facet_col = "ccon", 
  color = "fs", 
  check = "line", 
  custom = FALSE
)

Can a Neural Network capture the interactions with automatic feature engineering?

result <- nn(
  uber, 
  rvar = "price", 
  evar = c("time", "fs"), 
  type = "regression", 
  size = 2, 
  decay = 0.2,
  seed = 1234
)
summary(result, prn = TRUE)
Neural Network
Activation function  : Linear (regression)
Data                 : uber
Response variable    : price
Explanatory variables: time, fs 
Network size         : 2 
Parameter decay      : 0.2 
Seed                 : 1234 
Network              : 2-2-1 with 9 weights
Nr obs               : 1,000 
Weights              :
   b->h1 i1->h1 i2->h1 
   -1.25   0.92   0.87 
   b->h2 i1->h2 i2->h2 
    0.50  -1.13   2.12 
   b->o h1->o h2->o 
  -1.46  1.32  1.54  
pred <- predict(result, pred_cmd = c("time = 0:240", "fs = c('yes', 'no')"))
plot(pred, xvar = "time", color = "fs")

print(pred, n = 10)
Neural Network
Data                 : uber 
Response variable    : price 
Explanatory variables: time, fs 
Prediction command   : time = 0:240, fs = c('yes',  'no') 
Rows shown           : 10 of 482 

 time  fs Prediction
    0 yes      2.537
    1 yes      2.538
    2 yes      2.539
    3 yes      2.539
    4 yes      2.540
    5 yes      2.541
    6 yes      2.542
    7 yes      2.543
    8 yes      2.544
    9 yes      2.544
# cv.nn(result, size = 2, decay = seq(0,1,0.1))
visualize(
  uber,
  xvar = "time",
  yvar = "price",
  type = "scatter",
  custom = TRUE
) +
  geom_line(data = pred, aes(x = time, y = Prediction, color = fs), size = 1) +
  labs(color = "Friday/Saturday") + 
  scale_color_manual(values=c("red", "blue")) +
  theme(legend.position = "bottom")

result <- nn(
  uber, 
  rvar = "price", 
  evar = c("time", "fs", "ccon"), 
  type = "regression", 
  seed = 1234
)
summary(result, prn = TRUE)
Neural Network
Activation function  : Linear (regression)
Data                 : uber
Response variable    : price
Explanatory variables: time, fs, ccon 
Network size         : 1 
Parameter decay      : 0.5 
Seed                 : 1234 
Network              : 3-1-1 with 6 weights
Nr obs               : 1,000 
Weights              :
   b->h1 i1->h1 i2->h1 i3->h1 
   -1.51  -0.06   1.37   1.10 
   b->o h1->o 
  -0.72  2.40  
plot(result, plots = "garson", custom = FALSE)

pred <- predict(
  result, 
  pred_cmd = c(
    "time = 0:240", "fs = c('yes', 'no')", 
    "ccon = c('yes', 'no')"
  )
)
plot(pred, xvar = "time", facet_col = "ccon", color = "fs")

print(pred, n = 10)
Neural Network
Data                 : uber 
Response variable    : price 
Explanatory variables: time, fs, ccon 
Prediction command   : time = 0:240, fs = c('yes',  'no'), ccon = c('yes',  'no') 
Rows shown           : 10 of 964 

 time  fs ccon Prediction
    0 yes  yes      3.004
    1 yes  yes      3.004
    2 yes  yes      3.004
    3 yes  yes      3.004
    4 yes  yes      3.004
    5 yes  yes      3.004
    6 yes  yes      3.003
    7 yes  yes      3.003
    8 yes  yes      3.003
    9 yes  yes      3.003
result <- nn(
  uber, 
  rvar = "price", 
  evar = c("time", "fs", "ccon"), 
  type = "regression", 
  size = 2, 
  seed = 1234
)
summary(result, prn = TRUE)
Neural Network
Activation function  : Linear (regression)
Data                 : uber
Response variable    : price
Explanatory variables: time, fs, ccon 
Network size         : 2 
Parameter decay      : 0.5 
Seed                 : 1234 
Network              : 3-2-1 with 11 weights
Nr obs               : 1,000 
Weights              :
   b->h1 i1->h1 i2->h1 i3->h1 
   -1.40   0.59   0.69   1.39 
   b->h2 i1->h2 i2->h2 i3->h2 
   -0.53   1.04  -1.75   0.24 
   b->o h1->o h2->o 
  -0.12  2.02 -1.53  
plot(result, plots = "garson", custom = FALSE)

pred <- predict(
  result, 
  pred_cmd = c(
    "time = 0:240", "fs = c('yes', 'no')", 
    "ccon = c('yes', 'no')"
  )
)
plot(pred, xvar = "time", facet_col = "ccon", color = "fs")

print(pred, n = 10)
Neural Network
Data                 : uber 
Response variable    : price 
Explanatory variables: time, fs, ccon 
Prediction command   : time = 0:240, fs = c('yes',  'no'), ccon = c('yes',  'no') 
Rows shown           : 10 of 964 

 time  fs ccon Prediction
    0 yes  yes      2.907
    1 yes  yes      2.908
    2 yes  yes      2.909
    3 yes  yes      2.910
    4 yes  yes      2.911
    5 yes  yes      2.912
    6 yes  yes      2.913
    7 yes  yes      2.914
    8 yes  yes      2.915
    9 yes  yes      2.917

Equations

\[ price = a + b \times time \]

\[ price = a + b \times time + c \times fs \]

\[ price = a + b \times time + c \times 0 = a + b \times time \]

\[ price = a + b \times time + c \times 1 = a + c + b \times time \]

\[ price = a + b \times time + c \times fs + d \times time \times fs \]

\[ a + b \times time + c \times 0 + d \times time \times 0 \\ = a + b \times time \]

\[ a + b \times time + c \times 1 + d \times time \times 1 \\ = a + c + (b + d) \times time \]

\[ price = a + b \times time + c \times fs + d \times ccon \]

\[ price = a + b \times time + c \times fs + d \times ccon + e \times fs \times ccon \]

Friday/Saturday, Not Comic-Con

\[ a + b \times time + c \times 1 + d \times 0 + e \times 1 \times 0 \\ = a + c + b \times time \]

Not Friday/Saturday, Not Comic-Con

\[ a + b \times time + c \times 0 + d \times 0 + e \times 0 \times 0 \\ = a + b \times time \]

Friday/Saturday, Comic-Con

\[ a + b \times time + c \times 1 + d \times 1 + e \times 1 \times 1 \\ = a + c + d + e + b \times time \]

Not Friday/Saturday, Comic-Con

\[ a + b \times time + c \times 0 + d \times 1 + e \times 0 \times 1 \\ = a + d + b \times time \]

LS0tCnBhZ2V0aXRsZTogTm90ZWJvb2sgcmVwb3J0Cm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgaGlnaGxpZ2h0OiB6ZW5idXJuCiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciByX3NldHVwLCBpbmNsdWRlID0gRkFMU0V9CiMjIGluaXRpYWwgc2V0dGluZ3MKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGNvbW1lbnQgPSBOQSwKICBlY2hvID0gVFJVRSwKICBlcnJvciA9IFRSVUUsCiAgY2FjaGUgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UsCgogIGRwaSA9IDk2LAogIHdhcm5pbmcgPSBGQUxTRQopCgojIyB3aWR0aCB0byB1c2Ugd2hlbiBwcmludGluZyB0YWJsZXMgZXRjLgpvcHRpb25zKAogIHdpZHRoID0gMjUwLAogIHNjaXBlbiA9IDEwMCwKICBtYXgucHJpbnQgPSA1MDAwLAogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQopCgojIyBtYWtlIGFsbCByZXF1aXJlZCBsaWJyYXJpZXMgYXZhaWxhYmxlIGJ5IGxvYWRpbmcgcmFkaWFudCBwYWNrYWdlIGlmIG5lZWRlZAppZiAoaXMubnVsbChzaGlueTo6Z2V0RGVmYXVsdFJlYWN0aXZlRG9tYWluKCkpKSBsaWJyYXJ5KHJhZGlhbnQpCgojIyBpbmNsdWRlIGNvZGUgdG8gbG9hZCB0aGUgZGF0YSB5b3UgcmVxdWlyZQojIyBmb3IgaW50ZXJhY3RpdmUgdXNlIGF0dGFjaCB0aGUgcl9kYXRhIGVudmlyb25tZW50CiMgYXR0YWNoKHJfZGF0YSkKYGBgCgo8c3R5bGU+Ci5idG4sIC5mb3JtLWNvbnRyb2wsIHByZSwgY29kZSwgcHJlIGNvZGUgewogIGJvcmRlci1yYWRpdXM6IDRweDsKfQoudGFibGUgewogIHdpZHRoOiBhdXRvOwp9CnVsLCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAxOHB4Owp9CmNvZGUsIHByZSwgcHJlIGNvZGUgewogIG92ZXJmbG93OiBhdXRvOwogIHdoaXRlLXNwYWNlOiBwcmU7CiAgd29yZC13cmFwOiBub3JtYWw7Cn0KY29kZSB7CiAgY29sb3I6ICNjNzI1NGU7CiAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZjJmNDsKfQpwcmUgewogIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZmY7Cn0KPC9zdHlsZT4KCiMjIEludGVyYWN0aW9uIGV4YW1wbGU6IFViZXIgc3VyZ2UgcHJpY2luZwoKIyMjIERhdGEKCkxvYWRpbmcgdGhlIFViZXIgZmFyZXMgKHByaWNlKSBkYXRhOgoKCmBgYHtyfQojIyBMb2FkIGNvbW1hbmRzCnViZXIgPC0gcmVhZHI6OnJlYWRfcmRzKCJkYXRhL3ViZXIucmRzIikKcmVnaXN0ZXIoInViZXIiKQpgYGAKClNob3cgdGhlIGRhdGEgZGVzY3JpcHRpb24gZ2VuZXJhdGVkIGluIHRoZSBwcmV2aW91cyBzdGVwLiAKCmByIGF0dHIodWJlciwgImRlc2NyaXB0aW9uIilgIAoKQ2FsY3VsYXRlIHNvbWUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBvZiByaWRlIHByaWNlIHBlciBtaWxlIGluIHRoZSBkYXRhLgoKYGBge3J9CnJlc3VsdCA8LSBleHBsb3JlKAogIHViZXIsIAogIHZhcnMgPSAicHJpY2UiLCAKICBmdW4gPSBjKCJtZWFuIiwgInNkIiwgIm1pbiIsICJtYXgiKSwgCiAgbnIgPSAxCikKZHRhYihyZXN1bHQpICU+JSByZW5kZXIoKQpgYGAKClNob3cgYSBmcmVxdWVuY3kgdGFibGUgZm9yIGBmc2AgKGkuZS4sIGlzIGl0IEZyaWRheS9TYXR1cmRheSBvciBub3QpIGFuZCBgY2NvbmAgKGkuZS4sIGlzIENvbWljIENvbiBpbiB0b3duIG9yIG5vdCkKCmBgYHtyfQpyZXN1bHQgPC0gcGl2b3RyKHViZXIsIGN2YXJzID0gYygiZnMiLCAiY2NvbiIpLCBuciA9IDIpCmR0YWIocmVzdWx0KSAlPiUgcmVuZGVyKCkKYGBgCgpXaGF0IGRvIHRoZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiB0aGUgZGlmZmVyZW50IHZhcmlhYmxlcyBsb29rIGxpa2UuCgpgYGB7ciBmaWcud2lkdGggPSA3LjU0LCBmaWcuaGVpZ2h0ID0gNy41NCwgZHBpID0gMTQ0fQpyZXN1bHQgPC0gY29ycmVsYXRpb24oCiAgdWJlciwgCiAgdmFycyA9IGMoInByaWNlIiwgInRpbWUiLCAiZnMiLCAiY2NvbiIpCikKc3VtbWFyeShyZXN1bHQpCnBsb3QocmVzdWx0LCBucm9icyA9IDEwMDApCmBgYAoKIyMjIFF1ZXN0aW9ucyB0byBleHBsb3JlIGFuZCBlZmZlY3RzIHRvIGVzdGltYXRlCgoxLiBEb2VzIHRoZSAoc3RhcnQpIHRpbWUgKGB0aW1lYCkgb2YgYW4gVWJlciByaWRlIGFmZmVjdCB0aGUgcHJpY2U/IAoyLiBBcmUgcmlkZXMgb24gRnJpZGF5L1NhdHVyZGF5ICgieWVzIiBvciAibm8iKSBtb3JlIG9yIGxlc3MgZXhwZW5zaXZlIGNvbXBhcmVkIHRvIHJpZGVzIG9uIG90aGVyIGRheXM/IAozLiBEb2VzIHRoZSBlZmZlY3Qgb2YgKDEpIHRpbWUgb2YgcmlkZSBvbiBwcmljZSBkZXBlbmQgb24gKDIpIHRoZSBkYXkgb2YgdGhlIHJpZGUgKGkuZS4sIEZyaWRheS9TYXR1cmRheSBvciBub3QpCjQuIEFyZSByaWRlcyBtb3JlIG9yIGxlc3MgZXhwZW5zaXZlIHdoZW4gQ29taWNDb24gaXMgaW4gdG93biAoaS5lLiwgInllcyIgb3IgIm5vIik/IAo1LiBEb2VzIHRoZSAoMSkgQ29taWMgQ29uIGVmZmVjdCBvbiBwcmljZSBkZXBlbmQgb24gKDIpIHRoZSBkYXkgb2YgdGhlIHJpZGUgKGkuZS4sIEZyaWRheS9TYXR1cmRheSBvciBub3QpPyAKCgojIyMjIFF1ZXN0aW9uIDE6IERvZXMgdGhlIChzdGFydCkgdGltZSBvZiByaWRlIGFmZmVjdCB0aGUgcHJpY2U/IAoKTGV0cyBzdGFydCBieSB2aXN1YWxpemluZyBpZiB0aGVyZSBzZWVtcyB0byBiZSBhIGxpbmsgYmV0d2VlbiB0aGUgYHRpbWVgIGFuZCBgcHJpY2VgIHZhcmlhYmxlcyBpbiB0aGUgZGF0YS4gCgpgYGB7ciBmaWcud2lkdGggPSA1LCBmaWcuaGVpZ2h0ID0gNSwgZHBpID0gMjg4fQp2aXN1YWxpemUoCiAgdWJlciwgCiAgeHZhciA9ICJ0aW1lIiwgCiAgeXZhciA9ICJwcmljZSIsIAogIHR5cGUgPSAic2NhdHRlciIsIAogIG5yb2JzID0gLTEsIAogIGNoZWNrID0gImxpbmUiLCAKICBjdXN0b20gPSBGQUxTRQopCmBgYAoKTG9va2luZyBhdCB0aGUgZ3JhcGgsIHRoZSBsaW5lIHNlZW1zIHRvIGJlIGRvd253YXJkIHNsb3BwaW5nIGJ1dCB0aGUgZWZmZWN0IGxvb2tzIHByZXR0eSBtaW5pbWFsLgoKV2Ugd2lsbCB1c2UgbGluZWFyIHJlZ3Jlc3Npb24gKF9Nb2RlbCA+IExpbmVhciByZWdyZXNzaW9uXykgdG8gZXN0aW1hdGUgdGhlIGVmZmVjdCBvZiBgdGltZWAgb24gYHByaWNlYCBhbmQgZ2VuZXJhdGUgYSBwcmVkaWN0aW9uIHBsb3QuCgokJApwcmljZSA9IGEgKyBiIFx0aW1lcyB0aW1lCiQkCgpgYGB7ciBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNS4zOCwgZHBpID0gMTQ0fQpyZXN1bHQgPC0gcmVncmVzcygKICB1YmVyLCAKICBydmFyID0gInByaWNlIiwgCiAgZXZhciA9ICJ0aW1lIgopCnN1bW1hcnkocmVzdWx0LCBkZWMgPSA0KQpwcmVkIDwtIHByZWRpY3QoCiAgcmVzdWx0LCAKICBwcmVkX2NtZCA9ICJ0aW1lID0gMDoyNDAiCikKcGxvdChwcmVkLCB4dmFyID0gInRpbWUiKQpgYGAKCkFsdGhvdWdoIHRoZSBzbG9wZSBpbiB0aGlzIChwcmVkaWN0aW9uKSBwbG90IGxvb2tzIG1vcmUgaW1wcmVzc2l2ZSB0aGlzIGlzIGEgYml0IG1pc2xlYWRpbmcgZHVlIHRvIHRoZSBZLWF4aXMgc2NhbGUgKGkuZS4sIGNvbXBhcmUgdG8gdGhlIHNjYXR0ZXIgcGxvdCkuIFRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50IGZvciBgdGltZWAgaXMgbmVnYXRpdmUgYnV0IG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChpLmUuLCBwLXZhbHVlID4gMC4wNSkKCiMjIyMgUXVlc3Rpb24gMi4gQXJlIHJpZGVzIGlzIG9uIEZyaWRheS9TYXR1cmRheSAoInllcyIgb3IgIm5vIikgbW9yZSBvciBsZXNzIGV4cGVuc2l2ZT8gCgpXZSB3aWxsIHVzZSBsaW5lYXIgcmVncmVzc2lvbiAoX01vZGVsID4gTGluZWFyIHJlZ3Jlc3Npb25fKSB0byBlc3RpbWF0ZSB0aGUgZWZmZWN0IG9mIGBmc2Agb24gYHByaWNlYCwgY29udHJvbGxpbmcgZm9yIGB0aW1lYCwgYW5kIGdlbmVyYXRlIGEgcHJlZGljdGlvbiBwbG90LgoKYGBge3IgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDUuMzgsIGRwaSA9IDE0NH0KcmVzdWx0IDwtIHJlZ3Jlc3ModWJlciwgcnZhciA9ICJwcmljZSIsICBldmFyID0gYygidGltZSIsICJmcyIpKQpzdW1tYXJ5KHJlc3VsdCwgZGVjID0gNCkKcHJlZCA8LSBwcmVkaWN0KAogIHJlc3VsdCwgCiAgcHJlZF9jbWQgPSBjKCJ0aW1lID0gMDoyNDAiLCAiZnMgPSBjKCdubycsICd5ZXMnKSIpCikKcGxvdChwcmVkLCB4dmFyID0gInRpbWUiLCBjb2xvciA9ICJmcyIpCmBgYAoKVGhlIHBsb3Qgc2hvdyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBwcmljZXMgY2hhcmdlZCBvbiBGcmlkYXkgYW5kIFNhdHVyZGF5IGV2ZW5pbmcsIGNvbXBhcmVkIHRvIHRoZSBvdGhlciBkYXlzIG9mIHRoZSB3ZWVrLiBUaGUgc2xvcGUgb2YgdGhlIGxpbmVzIGlzLCBieSBhc3N1bXB0aW9uLCB0aGUgc2FtZSBpbiB0aGlzIG1vZGVsLgoKTm93IHRoYXQgd2UgaGF2ZSBpbmNsdWRlZCBgdGltZWAgYW5kIGBmc2AgaW4gdGhlIG1vZGVsIGB0aW1lYCBkb2VzIHNlZW0gdG8gaGF2ZSBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZG93bndhcmQgZWZmZWN0LgoKYGBge3IgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDQsIGRwaSA9IDI4OH0KY29lZmYgPC0gcmVzdWx0JGNvZWZmJGNvZWZmaWNpZW50ICU+JSAKICBzZXRfbmFtZXMocmVzdWx0JGNvZWZmJGxhYmVsKQoKdmlzdWFsaXplKAogIHViZXIsCiAgeHZhciA9ICJ0aW1lIiwKICB5dmFyID0gInByaWNlIiwKICB0eXBlID0gInNjYXR0ZXIiLAogIGN1c3RvbSA9IFRSVUUKKSArCiAgZ2VvbV9hYmxpbmUoCiAgICBhZXMoCiAgICAgIGludGVyY2VwdCA9IGNvZWZmWyIoSW50ZXJjZXB0KSJdLCAKICAgICAgc2xvcGUgPSBjb2VmZlsidGltZSJdLCAKICAgICAgY29sb3IgPSAiYmx1ZSIKICAgICksIAogICAgc2l6ZSA9IDEKICApICsKICBnZW9tX2FibGluZSgKICAgIGFlcygKICAgICAgaW50ZXJjZXB0ID0gY29lZmZbIihJbnRlcmNlcHQpIl0gKyBjb2VmZlsiZnN8eWVzIl0sIAogICAgICBzbG9wZSA9IGNvZWZmWyJ0aW1lIl0sIAogICAgICBjb2xvciA9ICJyZWQiCiAgICApLCAKICAgIHNpemUgPSAxCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgbmFtZSA9ICJGcmlkYXkvU2F0dXJkYXkiLAogICAgdmFsdWVzID0gYyhibHVlID0gImJsdWUiLCByZWQgPSAicmVkIiksCiAgICBsYWJlbHMgPSBjKCJubyIsICJ5ZXMiKQogICAgCiAgKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCgojIyMjIFF1ZXN0aW9uIDMuIERvZXMgdGhlIGVmZmVjdCBvZiAoMSkgdGltZSBvZiByaWRlIG9uIHByaWNlIGRlcGVuZCBvbiAoMikgdGhlIGRheSBvZiB0aGUgcmlkZSAoaS5lLiwgRnJpZGF5L1NhdHVyZGF5IG9yIG5vdCkKCkFub3RoZXIgd2F5IHRvIHN0YXRlIHRoZSBxdWVzdGlvbiBpcyB0byBhc2sgaWYgaXQgaXMgcmVhc29uYWJsZSB0aGF0IHRoZSBzbG9wZSBvZiBgdGltZWAgaW4gdGhlIHByZXZpb3VzIHByZWRpY3Rpb24gcGxvdCBpcyB0aGUgc2FtZSBmb3IgcmlkZXMgb24gRnJpZGF5IGFuZCBTYXR1cmRheSBhcyBpdCBpcyBvbiBvdGhlciBkYXlzLgoKSWYgd2UgYXNzdW1lIHRoYXQgVWJlciBpcyBmcmVxdWVudGx5IHVzZWQgaW4gdGhlIChsYXRlKSBldmVuaW5nIGJ5IHVzZXJzIHZpc2l0aW5nIGJhcnMgZG93bnRvd24sIHRoaXMgbWF5IGFzc3VtcHRpb24gb2YgImVxdWFsIHNsb3BlcyIgbWF5IG5vdCBiZSByZWFzb25hYmxlLgoKV2Ugd2lsbCB1c2UgbGluZWFyIHJlZ3Jlc3Npb24gKF9Nb2RlbCA+IExpbmVhciByZWdyZXNzaW9uXykgdG8gZXN0aW1hdGUgdGhlIGVmZmVjdCBvZiBgZnNgLCBgdGltZWAsIGFuZCBpbnRlcmFjdGlvbiBiZXR3ZWVuIGBmc2AgYW5kIGB0aW1lYCBvbiBgcHJpY2VgIGFuZCBnZW5lcmF0ZSBhIHByZWRpY3Rpb24gcGxvdC4KCmBgYHtyIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA1LjM4LCBkcGkgPSAxNDR9CnJlc3VsdCA8LSByZWdyZXNzKAogIHViZXIsIAogIHJ2YXIgPSAicHJpY2UiLCAKICBldmFyID0gYygidGltZSIsICJmcyIpLAogIGludCA9ICJ0aW1lOmZzIgopCnN1bW1hcnkocmVzdWx0KQpwcmVkIDwtIHByZWRpY3QoCiAgcmVzdWx0LCAKICBwcmVkX2NtZCA9IGMoInRpbWUgPSAwOjI0MCIsICJmcyA9IGMoJ25vJywgJ3llcycpIikKKQpwbG90KHByZWQsIHh2YXIgPSAidGltZSIsIGNvbG9yID0gImZzIikKYGBgCgpDcmVhdGluZyBhIHNjYXR0ZXIgcGxvdCBvZiB0aGUgbW9kZWwgcmVzdWx0cwoKYGBge3IgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDQsIGRwaSA9IDI4OH0KY29lZmYgPC0gcmVzdWx0JGNvZWZmJGNvZWZmaWNpZW50ICU+JSAKICBzZXRfbmFtZXMocmVzdWx0JGNvZWZmJGxhYmVsKQoKdmlzdWFsaXplKAogIHViZXIsCiAgeHZhciA9ICJ0aW1lIiwKICB5dmFyID0gInByaWNlIiwKICB0eXBlID0gInNjYXR0ZXIiLAogIGN1c3RvbSA9IFRSVUUKKSArCiAgZ2VvbV9hYmxpbmUoCiAgICBhZXMoCiAgICAgIGludGVyY2VwdCA9IGNvZWZmWyIoSW50ZXJjZXB0KSJdLCAKICAgICAgc2xvcGUgPSBjb2VmZlsidGltZSJdLCAKICAgICAgY29sb3IgPSAiYmx1ZSIKICAgICksIAogICAgc2l6ZSA9IDEKICApICsKICBnZW9tX2FibGluZSgKICAgIGFlcygKICAgICAgaW50ZXJjZXB0ID0gY29lZmZbIihJbnRlcmNlcHQpIl0gKyBjb2VmZlsiZnN8eWVzIl0sCiAgICAgIHNsb3BlID0gY29lZmZbInRpbWUiXSArIGNvZWZmWyJ0aW1lOmZzfHllcyJdLCAKICAgICAgY29sb3IgPSAicmVkIgogICAgKSwgCiAgICBzaXplID0gMQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIG5hbWUgPSAiRnJpZGF5L1NhdHVyZGF5IiwKICAgIHZhbHVlcyA9IGMoYmx1ZSA9ICJibHVlIiwgcmVkID0gInJlZCIpLAogICAgbGFiZWxzID0gYygibm8iLCAieWVzIikKICAgIAogICkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgoKVGhlIHByZWRpY3Rpb24gcGxvdCBwcm92aWRlcyBjb21wZWxsaW5nIGV2aWRlbmNlIHRoYXQgdGhlICJlcXVhbCBzbG9wZXMiIGFzc3VtcHRpb24gbWF5IG5vdCBiZSByZWFzb25hYmxlLiBXZSBkcmF3IGEgc2ltaWxhciBjb25jbHVzaW9uIGJ5IGxvb2tpbmcgYXQgYSBzY2F0dGVyIHBsb3Qgb2YgYHByaWNlYCBhbmQgYHRpbWVgIHdpdGggKipjb2xvcioqIHNldCB0byBgZnNgLgoKYGBge3IgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDQsIGRwaSA9IDIqMTQ0fQp2aXN1YWxpemUoCiAgdWJlciwgCiAgeHZhciA9ICJ0aW1lIiwgCiAgeXZhciA9ICJwcmljZSIsIAogIHR5cGUgPSAic2NhdHRlciIsIAogIG5yb2JzID0gLTEsIAogIGNvbG9yID0gImZzIiwgCiAgY2hlY2sgPSAibGluZSIsIAogIGN1c3RvbSA9IEZBTFNFCikKYGBgCgojIyMjIFF1ZXN0aW9uIDQuIEFyZSByaWRlcyBtb3JlIG9yIGxlc3MgZXhwZW5zaXZlIHdoZW4gQ29taWNDb24gaXMgaW4gdG93biAoaS5lLiwgInllcyIgb3IgIm5vIik/IAoKV2Ugd2lsbCB1c2UgbGluZWFyIHJlZ3Jlc3Npb24gKF9Nb2RlbCA+IExpbmVhciByZWdyZXNzaW9uXykgdG8gZXN0aW1hdGUgdGhlIGVmZmVjdCBvZiBgdGltZWAsIGBmc2AsIGBjY29uYCBvbiBgcHJpY2VgIGFuZCBnZW5lcmF0ZSBhIHByZWRpY3Rpb24gcGxvdC4gVG8gc2ltcGxpZnkgdGhlIGludGVycHJldGF0aW9uIGxldHMgcmVtb3ZlIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGB0aW1lYCBhbmQgYGZzYC4KCmBgYHtyIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA1LjM4LCBkcGkgPSAxNDR9CnJlc3VsdCA8LSByZWdyZXNzKAogIHViZXIsIAogIHJ2YXIgPSAicHJpY2UiLCAKICBldmFyID0gYygidGltZSIsICJmcyIsICJjY29uIiksIAopCnN1bW1hcnkocmVzdWx0LCBkZWMgPSA0KQpwcmVkIDwtIHByZWRpY3QoCiAgcmVzdWx0LCAKICBwcmVkX2NtZCA9IGMoInRpbWUgPSAwOjI0MCIsICJjY29uID0gYygnbm8nLCAneWVzJykiKQopCnBsb3QocHJlZCwgeHZhciA9ICJ0aW1lIiwgY29sb3IgPSAiY2NvbiIpCmBgYAoKVGhlIHByZWRpY3Rpb24gcGxvdCBwcm92aWRlcyBjb21wZWxsaW5nIGV2aWRlbmNlIHRoYXQgcmlkZXMgYXJlIG1vcmUgZXhwZW5zaXZlIGR1cmluZyBDb21pYyBDb24uIAoKIyMjIyBRdWVzdGlvbiA1LiBEb2VzIHRoZSAoMSkgQ29taWMgQ29uIGVmZmVjdCBvbiBwcmljZSBkZXBlbmQgb24gKDIpIHRoZSBkYXkgb2YgdGhlIHJpZGUgKGkuZS4sIEZyaWRheS9TYXR1cmRheSBvciBub3QpPyAKCkFub3RoZXIgd2F5IHRvIHN0YXRlIHRoZSBxdWVzdGlvbiBpcyB0byBhc2sgaWYgaXQgaXMgcmVhc29uYWJsZSB0aGF0IHRoZSBkaWZmZXJlbmNlIGluIHByaWNlIGJldHdlZW4gRnJpZGF5L1NhdHVyZGF5IGFuZCBvbiBvdGhlciBkYXlzIGlzIHRoZSBzYW1lIHdoZW4gQ29taWMgQ29uIGlzIChub3QpIGluIHRvd24uCgpXZSB3aWxsIHVzZSBsaW5lYXIgcmVncmVzc2lvbiAoX01vZGVsID4gTGluZWFyIHJlZ3Jlc3Npb25fKSB0byBlc3RpbWF0ZSB0aGUgZWZmZWN0IG9mIGB0aW1lYCwgYGZzYCwgYW5kIGBjY29uYCBhbmQgaW50ZXJhY3Rpb24gYmV0d2VlbiBgZnNgIGFuZCBgY2NvbmAgb24gYHByaWNlYCBhbmQgZ2VuZXJhdGUgYSBwcmVkaWN0aW9uIHBsb3QuCgpgYGB7ciBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNS4zOCwgZHBpID0gMTQ0fQpyZXN1bHQgPC0gcmVncmVzcygKICB1YmVyLCAKICBydmFyID0gInByaWNlIiwgCiAgZXZhciA9IGMoInRpbWUiLCAiZnMiLCAiY2NvbiIpLCAKICBpbnQgPSAiZnM6Y2NvbiIKKQpzdW1tYXJ5KHJlc3VsdCwgZGVjID0gNCkKcHJlZCA8LSBwcmVkaWN0KAogIHJlc3VsdCwgCiAgcHJlZF9jbWQgPSBjKCJ0aW1lID0gMDoyNDAiLCAiZnMgPSBjKCdubycsICd5ZXMnKSIsICJjY29uID0gYygnbm8nLCAneWVzJykiKQopCnBsb3QocHJlZCwgeHZhciA9ICJ0aW1lIiwgZmFjZXRfY29sID0gImNjb24iLCBjb2xvciA9ICJmcyIpCnByZWRpY3QoCiAgcmVzdWx0LCAKICBwcmVkX2NtZCA9IGMoInRpbWUgPSAwIiwgImZzID0gYygnbm8nLCAneWVzJykiLCAiY2NvbiA9IGMoJ25vJywgJ3llcycpIiksCiAgZGVjID0gMwopCmBgYAoKYGBge3IgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDQuNCwgZHBpID0gMjg4fQpjb2VmZiA8LSByZXN1bHQkY29lZmYkY29lZmZpY2llbnQgJT4lIAogIHNldF9uYW1lcyhyZXN1bHQkY29lZmYkbGFiZWwpCgp2aXN1YWxpemUoCiAgdWJlciwKICB4dmFyID0gInRpbWUiLAogIHl2YXIgPSAicHJpY2UiLAogIHR5cGUgPSAic2NhdHRlciIsCiAgY3VzdG9tID0gVFJVRQopICsKICBnZW9tX2FibGluZSgKICAgIGFlcygKICAgICAgaW50ZXJjZXB0ID0gY29lZmZbIihJbnRlcmNlcHQpIl0gKyBjb2VmZlsiZnN8eWVzIl0gKyBjb2VmZlsiY2Nvbnx5ZXMiXSwKICAgICAgc2xvcGUgPSBjb2VmZlsidGltZSJdLCAKICAgICAgY29sb3IgPSAiYmx1ZSIKICAgICksIAogICAgc2l6ZSA9IDEKICApICsKICBnZW9tX2FibGluZSgKICAgIGFlcygKICAgICAgaW50ZXJjZXB0ID0gY29lZmZbIihJbnRlcmNlcHQpIl0sIAogICAgICBzbG9wZSA9IGNvZWZmWyJ0aW1lIl0sIAogICAgICBjb2xvciA9ICJibGFjayIKICAgICksIAogICAgc2l6ZSA9IDEKICApICsKICBnZW9tX2FibGluZSgKICAgIGFlcygKICAgICAgaW50ZXJjZXB0ID0gY29lZmZbIihJbnRlcmNlcHQpIl0gKyBjb2VmZlsiZnN8eWVzIl0sCiAgICAgIHNsb3BlID0gY29lZmZbInRpbWUiXSwgCiAgICAgIGNvbG9yID0gInJlZCIKICAgICksIAogICAgc2l6ZSA9IDEKICApICsKICBnZW9tX2FibGluZSgKICAgIGFlcygKICAgICAgaW50ZXJjZXB0ID0gY29lZmZbIihJbnRlcmNlcHQpIl0gKyBjb2VmZlsiY2Nvbnx5ZXMiXSwKICAgICAgc2xvcGUgPSBjb2VmZlsidGltZSJdLCAKICAgICAgY29sb3IgPSAiZ3JlZW4iCiAgICApLCAKICAgIHNpemUgPSAxCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgbmFtZSA9ICJGcmlkYXkvU2F0dXJkYXkiLAogICAgdmFsdWVzID0gYyhibHVlID0gImJsdWUiLCByZWQgPSAicmVkIiwgYmxhY2sgPSAiYmxhY2siLCBncmVlbiA9ICJncmVlbiIpLAogICAgbGFiZWxzID0gYygibm8gZnMgKyBubyBjY29uIiwgImZzICsgY2NvbiIsICJubyBmcyArIGNjb24iLCAiZnMgKyBubyBjY29uIikKICAgIAogICkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgoKIyMgVGhlIGZpbmFsIG1vZGVsCgpUaGUgcHJldmlvdXMgbW9kZWwgd2FzIG1pc3NpbmcgdGhlIGltcG9ydGFudCBpbnRlcmFjdGlvbiBlZmZlY3QgYmV0d2VlbiBgdGltZWAgYW5kIGBmc2AuIExldHMgbm93IGFkZCB0aGF0IGJhY2sgaW4uIFRoaXMgZmluYWwgbW9kZWwgY2FuIGJlIHVzZWQgdG8gYW5zd2VyIGVhY2ggb2YgdGhlIHByZXZpb3VzIHF1ZXN0aW9uLgoKYGBge3IgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDQsIGRwaSA9IDI4OH0KcmVzdWx0IDwtIHJlZ3Jlc3MoCiAgdWJlciwgCiAgcnZhciA9ICJwcmljZSIsIAogIGV2YXIgPSBjKCJ0aW1lIiwgImZzIiwgImNjb24iKSwgCiAgaW50ID0gYygidGltZTpmcyIsICJmczpjY29uIikKKQpzdW1tYXJ5KHJlc3VsdCkKcHJlZCA8LSBwcmVkaWN0KAogIHJlc3VsdCwgCiAgcHJlZF9jbWQgPSBjKCJ0aW1lID0gMDoyNDAiLCAiZnMgPSBjKCdubycsICd5ZXMnKSIsICJjY29uID0gYygnbm8nLCAneWVzJykiKQopCnBsb3QocHJlZCwgeHZhciA9ICJ0aW1lIiwgZmFjZXRfY29sID0gImNjb24iLCBjb2xvciA9ICJmcyIpCmBgYAoKRmluYWxseSwgbGV0cyB2aXN1YWxpemUgdGhlIGVmZmVjdHMgaW4gYSBzY2F0dGVyIHBsb3QuIExvb2tzIGEgKipsb3QqKiBsaWtlIHRoZSBwcmVkaWN0aW9uIHBsb3RzIGZyb20gdGhlIGxhc3QgcmVncmVzc2lvbgoKYGBge3IgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDQsIGRwaSA9IDI4OH0KdmlzdWFsaXplKAogIHViZXIsIAogIHh2YXIgPSAidGltZSIsIAogIHl2YXIgPSAicHJpY2UiLCAKICB0eXBlID0gInNjYXR0ZXIiLCAKICBucm9icyA9IC0xLCAKICBmYWNldF9jb2wgPSAiY2NvbiIsIAogIGNvbG9yID0gImZzIiwgCiAgY2hlY2sgPSAibGluZSIsIAogIGN1c3RvbSA9IEZBTFNFCikKYGBgCgojIyBDYW4gYSBOZXVyYWwgTmV0d29yayBjYXB0dXJlIHRoZSBpbnRlcmFjdGlvbnMgd2l0aCBhdXRvbWF0aWMgZmVhdHVyZSBlbmdpbmVlcmluZz8KCgpgYGB7ciBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNS4zOCwgZHBpID0gMTQ0fQpyZXN1bHQgPC0gbm4oCiAgdWJlciwgCiAgcnZhciA9ICJwcmljZSIsIAogIGV2YXIgPSBjKCJ0aW1lIiwgImZzIiksIAogIHR5cGUgPSAicmVncmVzc2lvbiIsIAogIHNpemUgPSAyLCAKICBkZWNheSA9IDAuMiwKICBzZWVkID0gMTIzNAopCnN1bW1hcnkocmVzdWx0LCBwcm4gPSBUUlVFKQpwcmVkIDwtIHByZWRpY3QocmVzdWx0LCBwcmVkX2NtZCA9IGMoInRpbWUgPSAwOjI0MCIsICJmcyA9IGMoJ3llcycsICdubycpIikpCnBsb3QocHJlZCwgeHZhciA9ICJ0aW1lIiwgY29sb3IgPSAiZnMiKQpwcmludChwcmVkLCBuID0gMTApCiMgY3Yubm4ocmVzdWx0LCBzaXplID0gMiwgZGVjYXkgPSBzZXEoMCwxLDAuMSkpCmBgYAoKYGBge3IgZmlnLndpZHRoID0gNSwgZmlnLmhlaWdodCA9IDQsIGRwaSA9IDI4OH0KdmlzdWFsaXplKAogIHViZXIsCiAgeHZhciA9ICJ0aW1lIiwKICB5dmFyID0gInByaWNlIiwKICB0eXBlID0gInNjYXR0ZXIiLAogIGN1c3RvbSA9IFRSVUUKKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBwcmVkLCBhZXMoeCA9IHRpbWUsIHkgPSBQcmVkaWN0aW9uLCBjb2xvciA9IGZzKSwgc2l6ZSA9IDEpICsKICBsYWJzKGNvbG9yID0gIkZyaWRheS9TYXR1cmRheSIpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJyZWQiLCAiYmx1ZSIpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAogIApgYGB7ciBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gNS4zOCwgZHBpID0gMTQ0fQpyZXN1bHQgPC0gbm4oCiAgdWJlciwgCiAgcnZhciA9ICJwcmljZSIsIAogIGV2YXIgPSBjKCJ0aW1lIiwgImZzIiwgImNjb24iKSwgCiAgdHlwZSA9ICJyZWdyZXNzaW9uIiwgCiAgc2VlZCA9IDEyMzQKKQpzdW1tYXJ5KHJlc3VsdCwgcHJuID0gVFJVRSkKcGxvdChyZXN1bHQsIHBsb3RzID0gImdhcnNvbiIsIGN1c3RvbSA9IEZBTFNFKQpwcmVkIDwtIHByZWRpY3QoCiAgcmVzdWx0LCAKICBwcmVkX2NtZCA9IGMoCiAgICAidGltZSA9IDA6MjQwIiwgImZzID0gYygneWVzJywgJ25vJykiLCAKICAgICJjY29uID0gYygneWVzJywgJ25vJykiCiAgKQopCnBsb3QocHJlZCwgeHZhciA9ICJ0aW1lIiwgZmFjZXRfY29sID0gImNjb24iLCBjb2xvciA9ICJmcyIpCnByaW50KHByZWQsIG4gPSAxMCkKYGBgCgoKYGBge3IgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDUuMzgsIGRwaSA9IDE0NH0KcmVzdWx0IDwtIG5uKAogIHViZXIsIAogIHJ2YXIgPSAicHJpY2UiLCAKICBldmFyID0gYygidGltZSIsICJmcyIsICJjY29uIiksIAogIHR5cGUgPSAicmVncmVzc2lvbiIsIAogIHNpemUgPSAyLCAKICBzZWVkID0gMTIzNAopCnN1bW1hcnkocmVzdWx0LCBwcm4gPSBUUlVFKQpwbG90KHJlc3VsdCwgcGxvdHMgPSAiZ2Fyc29uIiwgY3VzdG9tID0gRkFMU0UpCnByZWQgPC0gcHJlZGljdCgKICByZXN1bHQsIAogIHByZWRfY21kID0gYygKICAgICJ0aW1lID0gMDoyNDAiLCAiZnMgPSBjKCd5ZXMnLCAnbm8nKSIsIAogICAgImNjb24gPSBjKCd5ZXMnLCAnbm8nKSIKICApCikKcGxvdChwcmVkLCB4dmFyID0gInRpbWUiLCBmYWNldF9jb2wgPSAiY2NvbiIsIGNvbG9yID0gImZzIikKcHJpbnQocHJlZCwgbiA9IDEwKQpgYGAKCgoKIyMgRXF1YXRpb25zCgokJApwcmljZSA9IGEgKyBiIFx0aW1lcyB0aW1lCiQkCgokJApwcmljZSA9IGEgKyBiIFx0aW1lcyB0aW1lICsgYyBcdGltZXMgZnMKJCQKCiQkCnByaWNlID0gYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyAwID0gYSArIGIgXHRpbWVzIHRpbWUKJCQKCiQkCnByaWNlID0gYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyAxID0gYSArIGMgKyBiIFx0aW1lcyB0aW1lCiQkCgokJApwcmljZSA9IGEgKyBiIFx0aW1lcyB0aW1lICsgYyBcdGltZXMgZnMgKyBkIFx0aW1lcyB0aW1lIFx0aW1lcyBmcwokJAoKJCQKYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyAwICsgZCBcdGltZXMgdGltZSBcdGltZXMgMCBcXAo9IGEgKyBiIFx0aW1lcyB0aW1lIAokJAoKJCQKYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyAxICsgZCBcdGltZXMgdGltZSBcdGltZXMgMSBcXAo9IGEgKyBjICsgKGIgKyBkKSBcdGltZXMgdGltZSAKJCQKCiQkCnByaWNlID0gYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyBmcyArIGQgXHRpbWVzIGNjb24KJCQKCiQkCnByaWNlID0gYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyBmcyArIGQgXHRpbWVzIGNjb24gKyBlIFx0aW1lcyBmcyBcdGltZXMgY2NvbgokJAoKRnJpZGF5L1NhdHVyZGF5LCBOb3QgQ29taWMtQ29uCgokJAphICsgYiBcdGltZXMgdGltZSArIGMgXHRpbWVzIDEgKyBkIFx0aW1lcyAwICsgZSBcdGltZXMgMSBcdGltZXMgMCBcXAo9IGEgKyBjICsgYiBcdGltZXMgdGltZQokJAoKTm90IEZyaWRheS9TYXR1cmRheSwgTm90IENvbWljLUNvbgoKJCQKYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyAwICsgZCBcdGltZXMgMCArIGUgXHRpbWVzIDAgXHRpbWVzIDAgXFwKPSBhICsgYiBcdGltZXMgdGltZQokJAoKRnJpZGF5L1NhdHVyZGF5LCBDb21pYy1Db24KCiQkCmEgKyBiIFx0aW1lcyB0aW1lICsgYyBcdGltZXMgMSArIGQgXHRpbWVzIDEgKyBlIFx0aW1lcyAxIFx0aW1lcyAxIFxcCj0gYSArIGMgKyBkICsgZSArIGIgXHRpbWVzIHRpbWUKJCQKCk5vdCBGcmlkYXkvU2F0dXJkYXksIENvbWljLUNvbgoKJCQKYSArIGIgXHRpbWVzIHRpbWUgKyBjIFx0aW1lcyAwICsgZCBcdGltZXMgMSArIGUgXHRpbWVzIDAgXHRpbWVzIDEgXFwKPSBhICsgZCArIGIgXHRpbWVzIHRpbWUKJCQKCgo=